<script setup>
import ChatMessage from '@/views/chat/components/ChatMessage.vue'
import ChatInput from '@/views/chat/components/ChatInput.vue'
import { ref, computed, onMounted, watch, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import moment from 'moment'
import { courseChat } from '@/api/chat.js'
import { ElMessage } from 'element-plus'
import { isObjectJson } from '@/utils/index.js'
import useUserStore from '@/stores/user.js'
import { md5 } from 'js-md5'

const histories = ref([])
const isOutAct = ref(false)
const aiOutput = ref('')
const disable = ref(false)
let controller = null
const userStore = useUserStore()

const route = useRoute()
const history_storage_key = ref('history-storage-key-')
const loaded = ref(false)

onMounted(() => {
  history_storage_key.value += route.query.course_id + '-'
    + md5(userStore.getToken).substring(0, 16)
  const storage_history = window.localStorage.getItem(history_storage_key.value)
  if (storage_history) {
    histories.value = JSON.parse(storage_history)
  }
  nextTick(() => {
    loaded.value = true
  })
})

const clear_history = () => {
  histories.value = []
}

watch(() => histories.value, (newValue) => {
  if (loaded.value) {
    console.log(newValue)
    window.localStorage.setItem(history_storage_key.value, JSON.stringify(newValue))
  }
}, {deep: true})

const aiHistories = computed(() => {
  const h = [
    {
      content: 'Hi，欢迎使用 AI 智能问答，可以为你解答资料相关的任何问题！',
      role: 'assistant',
      file_names: [],
      time: moment().format('YYYY-MM-DD HH:mm:ss'),
    },
  ]
  return h.concat(histories.value)
})

const httpHistories = () => {
  const list = histories.value.slice(-8)
  return list.map(item => {
    const { role, content } = item
    return {
      role,
      content: content,
    }
  })
}

/**
 * @param {String} content
 */
const requestChat = (content) => {
  disable.value = true
  courseChat({
    query: content,
    course_id: route.query.course_id,
    history: httpHistories(),
  }).then(({ reader, control }) => {
    controller = control
    isOutAct.value = true
    histories.value.push({
      role: 'user',
      content: content,
      time: moment().format('YYYY-MM-DD HH:mm:ss'),
    })
    handleReader(reader)
  }).catch(() => {
    isOutAct.value = false
    disable.value = false
  })
}

const handleReader = async (reader) => {
  let d, v
  try {
    const { value, done } = await reader.read()
    d = done
    v = value
  } catch (e) {
    d = true
  }
  const decoder = new TextDecoder()
  if (!d) {
    let data = decoder.decode(v.buffer)
    aiOutput.value += data
    await handleReader(reader)
  } else {
    const json = isObjectJson(aiOutput.value)
    if (json !== false && json.code !== 200) {
      aiOutput.value = ''
      disable.value = false
      isOutAct.value = false
      ElMessage.error(json.message)
    } else {
      if (aiOutput.value) {
        histories.value.push({
          content: aiOutput.value,
          role: 'assistant',
          time: moment().format('YYYY-MM-DD HH:mm:ss'),
        })
      }
      aiOutput.value = ''
      isOutAct.value = false
      disable.value = false
    }
  }
}

const stopAnswer = () => {
  if (controller !== null) controller.abort()
  histories.value.push({
    content: aiOutput.value,
    role: 'assistant',
    time: moment().format("YYYY-MM-DD HH:mm:ss")
  })
  aiOutput.value = ''
  isOutAct.value = false
  disable.value = false
}
</script>

<template>
  <div>
    <chat-message
      :histories="aiHistories" :is-out-act="isOutAct" :ai-output="aiOutput" :disable="disable"
      :show-tools="false" custom-class="graph-chat"
    />
    <chat-input
      :disable="disable" :show-tools="false" :on-submit="requestChat" :stop-answer="stopAnswer"
      show-clear @on-clear="clear_history"
      placeholder="对课程内容以及资料内容进行提问。（Enter = 发送，Shift+Enter = 换行）"
    />
  </div>
</template>

<style scoped lang="scss">
:deep(.sect) {
  width: 100% !important;
  height: calc(100% - 70px) !important;
  overflow: hidden;
}

:deep(.chat-section) {
  width: calc(100% + 50px);
  height: 100%;
  position: relative;
  left: 0;
  overflow-x: hidden;
  overflow-y: auto;
}

:deep(.chat-message-box>.user) {
  width: calc(100% - 50px);
}

:deep(.chat-message-box>.assistant) {
  width: calc(100% - 50px);
}
:deep(.graph-chat) {
  height: calc(100% - 100px) !important;
}
</style>